package solver1;

import java.awt.Point;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map.Entry;

import exercices.Trial;

public class SudokuSolver {
	private int[] _sollution;
	private Collection<SudokuState> states ;

	public void load(int[] sudoku) {
		states = new ArrayList<>();
		states.add(new SudokuState(sudoku));
	}

	public int[] solve() {

		return (_sollution == null) ? _sollution = _solve() : _sollution;

	}

	private int[] _solve() {
		int[] a = null;
		while (!states.isEmpty())
			for (SudokuState _state : consume(states)) {
				try {
					_state.resolveIssues();
				} catch (Exception e) {
					continue;//
				}

				if (_state.solved()) {
					a = _state.toList();
					Trial.myprint(a);
				} else
					branch(_state);
			}
		return a;
	}

	private void branch(SudokuState _state) {
		for (SudokuState state : _state.branchAt(chooseLocation(_state)))
			states.add(state);
	}

	private Point chooseLocation(SudokuState _state) {
		int miniumum = 9;
		Point result = null;
		for (Entry<Point, int[]> entry : _state.state.entrySet())
			if (entry.getValue().length > 1 && entry.getValue().length<miniumum)
			{
				result = entry.getKey();
				miniumum = entry.getValue().length;
			}
		return result;
	}

	private <T> Collection<T> consume(Collection<T> todo) {
		ArrayList<T> rv = new ArrayList<>(todo);
		todo.clear();
		return rv;
	}

}
